/*
 * 投中信息
 * Copyright 2017 (C) All Rights Reserved.
 */
package cn.studyjava.verify.util;

import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * <p>
 * Description:
 * </p>
 * 
 * @author: zsljava
 * @version 1.0.0
 * <p>
 * History:
 * -----------------------------------------------
 * @Date: 2017年10月17日 下午2:21:42
 * @author: zsljava
 * @version 1.0.0
 * @OP: Create
 * -----------------------------------------------
 * </p>
 *
 * @since
 * @see
 */
public class ThreadPoolExecutorUtil extends ThreadPoolExecutor {

	/**
	 * 核心线程池大小
	 */
	private static final int POOL_SIZE = 5;

	/**
	 * 最大线程池大小
	 */
	private static final int MAX_POLLSIZE = 10;

	/**
	 * 线程池中超过corePoolSize数目的空闲线程最大存活时间；可以allowCoreThreadTimeOut(true)使得核心线程有效时间
	 */
	private static final int KEEP_ALIVE_TIME = 1000;

	private Logger log = LoggerFactory.getLogger(ThreadPoolExecutorUtil.class);

	/**
	 * 
	 * @Title:ThreadPoolExecutorUtil
	 * @Description: 默认无参数构造器
	 */
	public ThreadPoolExecutorUtil() {
		super(POOL_SIZE, MAX_POLLSIZE, KEEP_ALIVE_TIME, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<Runnable>());
	}

	/**
	 * @Title: @Title:ThreadPoolExecutorUtil
	 * @Description: 自定义参数构造方法
	 * @param corePoolSize 核心线程池大小
	 * @param maximumPoolSize 最大线程池大小
	 * @param keepAliveTime  线程池中超过corePoolSize数目的空闲线程最大存活时间；可以allowCoreThreadTimeOut(true)使得核心线程有效时间
	 * @param unit keepAliveTime时间单位
	 * @param workQueue 阻塞任务队列
	 */
	public ThreadPoolExecutorUtil(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
			BlockingQueue<Runnable> workQueue) {
		super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
	}
	
	/**
	 * 
	 * @Title:ThreadPoolExecutorUtil
	 * @Description: 自定义参数构造方法
	 * @param corePoolSize 核心线程池大小
	 * @param maximumPoolSize 最大线程池大小
	 * @param keepAliveTime  线程池中超过corePoolSize数目的空闲线程最大存活时间；可以allowCoreThreadTimeOut(true)使得核心线程有效时间
	 * @param unit keepAliveTime时间单位
	 * @param workQueue 阻塞任务队列
	 * @param threadFactory 新建线程工厂
	 * @param handler 当提交任务数超过maxmumPoolSize+workQueue之和时，任务会交给RejectedExecutionHandler来处理
	 */
	public ThreadPoolExecutorUtil(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
			BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
		super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
	}
	

	@Override
	public void shutdown() {
		log.debug("ThreadPoolExecutorUtil: 服务关闭Going to shutdown.\n");
		log.debug("ThreadPoolExecutorUtil: Executed tasks: %d\n", getCompletedTaskCount());
		log.debug("ThreadPoolExecutorUtil: Running tasks: %d\n", getActiveCount());
		log.debug("ThreadPoolExecutorUtil: Pending tasks: %d\n", getQueue().size());
		super.shutdown();
	}


	@Override
	public List<Runnable> shutdownNow() {
		log.debug("ThreadPoolExecutorUtil: 服务立即关闭 Going to immediately shutdown.\n");
		log.debug("ThreadPoolExecutorUtil: Executed tasks: %d\n", getCompletedTaskCount());
		log.debug("ThreadPoolExecutorUtil: Running tasks: %d\n", getActiveCount());
		log.debug("ThreadPoolExecutorUtil: Pending tasks: %d\n", getQueue().size());
		return super.shutdownNow();
	}
	
	/**
	 * 
	 * @Title: finish
	 * @Description: 执行完成后返回主线程
	 * @return: void
	 */
	public void finish() {
		log.debug("ThreadPoolExecutorUtil: 服务执行完成后Going to finish return.\n");
		log.debug("ThreadPoolExecutorUtil: Executed tasks: %d\n", getCompletedTaskCount());
		log.debug("ThreadPoolExecutorUtil: Running tasks: %d\n", getActiveCount());
		log.debug("ThreadPoolExecutorUtil: Pending tasks: %d\n", getQueue().size());
		super.shutdown();
		try {
			boolean flag = true;
			while(flag){
				flag = !awaitTermination(1, TimeUnit.SECONDS);
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
